package com.mzba.place.fragment;

import java.util.List;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.FrameLayout;
import android.widget.Spinner;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragment;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.mzba.place.PlaceApplication;
import com.mzba.place.R;
import com.mzba.place.adapter.MyArrayAdapter;
import com.mzba.place.entity.ReportEntity;
import com.mzba.place.ui.MainActivity;
import com.mzba.place.ui.ReportDetailActivity;
import com.mzba.place.utils.AppContext;
import com.mzba.place.utils.BasicUIEvent;
import com.mzba.place.utils.UICore;
import com.mzba.place.utils.Utils;
/**
 * 
 * @author 06peng
 *
 */
public class MapFragment extends SherlockFragment implements Callback, MKMapViewListener, BasicUIEvent {
	
	private MainActivity mainActivity;
	public MapView mMapView = null;
	private MapController mMapController = null;
	public FrameLayout mainLayout = null;
	public View filterView;
	public PlaceApplication app;
	public LocationClient mLocClient;
	
	private List<ReportEntity> reports;
	public CursorAdapter suggestionAdapter;
	private Handler handler;
	private boolean isInit;
	private int latitude;
	private int longitude;
	private int current_latitude;
	private int current_longitude;
//	private String address;
	private Drawable mypositionDrawable;
	private Drawable marker1;
	private Drawable marker2;
	private Drawable marker3;
	private Drawable marker4;
	private ReportsOverlay overlays;
	private View popView;
	private float zoomLevel = 16;
	
	private final int show_position = 1;
	private final int load_reports_data = 2;
	private final int init_reports = 4;
	
	private boolean firstReportType;
	private boolean firstReportTime;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mainActivity = (MainActivity) getSherlockActivity();
		handler = new Handler(this);
		
		app = (PlaceApplication) mainActivity.getApplication();
        if (app.mBMapManager == null) {
            app.mBMapManager = new BMapManager(mainActivity);
            app.mBMapManager.init(PlaceApplication.strKey, new PlaceApplication.MyGeneralListener());
        }
        app.getMyListener().setHander(handler);
        mLocClient = app.mLocationClient;
        
        mypositionDrawable = mainActivity.getResources().getDrawable(R.drawable.ic_map_current_position);
        overlays = new ReportsOverlay(mypositionDrawable, mMapView);
        marker1 = mainActivity.getResources().getDrawable(R.drawable.ic_map_marker_01);
        marker2 = mainActivity.getResources().getDrawable(R.drawable.ic_map_marker_02);
        marker3 = mainActivity.getResources().getDrawable(R.drawable.ic_map_marker_03);
        marker4 = mainActivity.getResources().getDrawable(R.drawable.ic_map_marker_04);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		mainLayout = (FrameLayout) inflater.inflate(R.layout.map_fragment, null);
		mMapView = (MapView) mainLayout.findViewById(R.id.bmapView);
        mMapController = mMapView.getController();
        mMapController.enableClick(true);
        mMapController.setZoom(zoomLevel);
        mMapView.setDoubleClickZooming(true);
        mMapView.setOnTouchListener(mapTouchListener);
        mMapView.regMapViewListener(app.mBMapManager, this);
        popView = inflater.inflate(R.layout.map_popview_item, null);
		return mainLayout;
	}
	
	@Override
	public void onResume() {
		mMapView.setVisibility(View.VISIBLE);
		mMapView.onResume();
		mMapView.setDoubleClickZooming(true);
        mMapView.setOnTouchListener(mapTouchListener);
        mMapController.setScrollGesturesEnabled(true);
		super.onResume();
		initFilterView();
        initFilterTips();
		if (!isInit) {
			menuMyPosition();
		} else {
			handler.sendEmptyMessage(show_position);
		}
	}
	
	@Override
	public void onPause() {
//		mMapView.setVisibility(View.INVISIBLE);
		mMapView.onPause();
		super.onPause();
	}
	
	/**
	 * locate to my position
	 */
	public void menuMyPosition() {
		mainActivity.loading();
		new Thread() {
			public void run() {
				setLocationOption();
				if (mLocClient != null && mLocClient.isStarted()) {
					mLocClient.requestLocation();
				} else {
					mLocClient.start();
					mLocClient.requestLocation();
				}
			};
		}.start();
	}
	
	public void locateTo() {
		new Thread() {
			public void run() {
				/**
				 * if do not do this,app will stop running,maybe is a bug by baidu.
				 */
				if (latitude != 0 && longitude != 0) {
					try {
						Thread.sleep(500);
						handler.sendEmptyMessage(show_position);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
		}.start();
	}
	
	@Override
	public void onDestroyView() {
		mMapView.destroyDrawingCache();
		super.onDestroyView();
	}
	
	private View.OnTouchListener mapTouchListener = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				mMapView.removeView(popView);
				break;
			case MotionEvent.ACTION_MOVE:
				
				break;
			case MotionEvent.ACTION_UP:
				
				break;
			}
			return false;
		}
	};

//	private void initMKSearch() {
//		mSearch.init(app.mBMapManager, new MKSearchListener() {
//			
//			@Override
//			public void onGetWalkingRouteResult(MKWalkingRouteResult res, int error) { }
//			
//			@Override
//			public void onGetTransitRouteResult(MKTransitRouteResult res, int error) { }
//			
//			@Override
//			public void onGetSuggestionResult(MKSuggestionResult res, int error) { }
//			
//			@Override
//			public void onGetPoiResult(MKPoiResult arg0, int res, int error) { }
//			
//			@Override
//			public void onGetPoiDetailSearchResult(int res, int error) { }
//			
//			@Override
//			public void onGetDrivingRouteResult(MKDrivingRouteResult res, int error) { }
//			
//			@Override
//			public void onGetBusDetailResult(MKBusLineResult res, int error) { }
//			
//			@Override
//			public void onGetAddrResult(MKAddrInfo res, int error) { 
//				try {
//					if (error != 0) {
//						return;
//					}
//					if (res.geoPt != null) {
//						latitude = res.geoPt.getLatitudeE6();
//						longitude = res.geoPt.getLongitudeE6();
//						address = res.strAddr;
//						if (latitude != 0 && longitude != 0) {
//							GeoPoint gp = new GeoPoint(latitude, longitude);
//							overlays = new ReportsOverlay(mypositionDrawable, mMapView);
//							OverlayItem myOverlayIetm = new OverlayItem(gp, "", address);
//							myOverlayIetm.setMarker(mypositionDrawable);
//							overlays.addItem(myOverlayIetm);
//							mMapView.getOverlays().clear();
//							mMapView.getOverlays().add(overlays);
//							
//							mMapController.animateTo(gp);
//							mMapView.refresh();
//							try {
//								Thread.sleep(500);
//								handler.sendEmptyMessage(init_reports);
//							} catch (InterruptedException e) {
//								e.printStackTrace();
//							}
//						}
//					}
//				} catch (Exception e) {
//					e.printStackTrace();
//				}
//			}
//			
//		});
//	}
	
	

	@Override
	public boolean handleMessage(Message msg) {
		try {
			switch (msg.what) {
			case AppContext.LOCATE:
				mainActivity.destroyDialog();
				current_latitude = (int) (app.latitude * 1E6);
				current_longitude = (int) (app.longitude * 1E6);
				if (current_latitude != 0 && current_longitude != 0) {
					latitude = current_latitude;
					longitude = current_longitude;
					GeoPoint pt = new GeoPoint(current_latitude, current_longitude);
					mMapController.animateTo(pt);
					mMapView.refresh();
					Thread.sleep(500);
					handler.sendEmptyMessage(init_reports);
//					mSearch = new MKSearch();
//					initMKSearch();
//					mSearch.reverseGeocode(pt);
					isInit = true;
				}
				break;
			case show_position:
				GeoPoint gp = new GeoPoint(latitude, longitude);
				mMapController.animateTo(gp);
				Thread.sleep(500);
				handler.sendEmptyMessage(load_reports_data);
				break;
			case load_reports_data:
				try {
					showReports();
				} catch (Exception e) {
					e.printStackTrace();
				}
				loadFinish();
				break;
			case init_reports:
				load();
				break;
			default:
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	private void showReports() {
//		GeoPoint gp = new GeoPoint(latitude, longitude);
		overlays = new ReportsOverlay(mypositionDrawable, mMapView);
		overlays.removeAll();
//		if (myPosition) {
//			OverlayItem myOverlayIetm = new OverlayItem(gp, "", address);
//			myOverlayIetm.setMarker(mypositionDrawable);
//			overlays.addItem(myOverlayIetm);
//		}
		reports = mainActivity.getReports();
		if (reports != null && !reports.isEmpty()) {
			for (int i = 0;i < reports.size() && i <= 100;i++) {
				ReportEntity report = reports.get(i);
				GeoPoint pt = new GeoPoint((int) (report.getCoordinate().getLat() * 1E6), (int) (report.getCoordinate().getLon() * 1E6));
				ReportOverlayItem mOverlayIetm = new ReportOverlayItem(pt, "", report.getText());
				mOverlayIetm.setEntry(report);
				if (report.getType_id() == 1) {
					mOverlayIetm.setMarker(marker1);
				} else if (report.getType_id() == 2) {
					mOverlayIetm.setMarker(marker2);
				} else if (report.getType_id() == 3) {
					mOverlayIetm.setMarker(marker3);
				} else if (report.getType_id() == 4) {
					mOverlayIetm.setMarker(marker4);
				} else {
					mOverlayIetm.setMarker(marker4);
				}
				overlays.addItem(mOverlayIetm);
			}
		}
		mMapView.getOverlays().clear();
		mMapView.getOverlays().add(overlays);
		mMapView.refresh();
	}
	
	private void setLocationOption() {
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);			
		option.setCoorType("bd09ll");			
		option.setAddrType("all");	
		option.setScanSpan(0);
		option.setPriority(LocationClientOption.GpsFirst);      
		option.setPoiNumber(10);
		option.disableCache(true);		
		mLocClient.setLocOption(option);
	}
	
	public class ReportsOverlay extends ItemizedOverlay<OverlayItem> {
		
		public ReportsOverlay(Drawable drawable, MapView mapView) {
			super(drawable, mapView);
		}
		
		@Override
		public boolean onTap(GeoPoint pt, MapView mapView) {
			mMapView.removeView(popView);
			super.onTap(pt, mapView);
			return false;
		}
		
		@Override
		protected boolean onTap(int i) {
			try {
				final OverlayItem overlayItem = getItem(i);
				GeoPoint gp = overlayItem.getPoint();
				mMapView.addView(popView, new MapView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, gp, MapView.LayoutParams.BOTTOM_CENTER));
				TextView tv_title = (TextView) popView.findViewById(R.id.pop_title);
				tv_title.setText(overlayItem.getSnippet());
				popView.findViewById(R.id.imagebuttongo).setOnClickListener(new View.OnClickListener() {
					
					@Override
					public void onClick(View v) {
						mMapView.removeView(popView);
						if (overlayItem instanceof ReportOverlayItem) {
							ReportOverlayItem item = (ReportOverlayItem) overlayItem;
							Intent intent = new Intent();
							intent.setClass(mainActivity, ReportDetailActivity.class);
							intent.putExtra("report_detail", item.getEntry());
							startActivity(intent);
						}
					}
				});
				tv_title.setOnClickListener(new View.OnClickListener() {
					
					@Override
					public void onClick(View v) {
						mMapView.removeView(popView);
						if (overlayItem instanceof ReportOverlayItem) {
							ReportOverlayItem item = (ReportOverlayItem) overlayItem;
							Intent intent = new Intent();
							intent.setClass(mainActivity, ReportDetailActivity.class);
							intent.putExtra("report_detail", item.getEntry());
							startActivity(intent);
						}
						
					}
				});
			} catch (Exception e) {
				e.printStackTrace();
			}
			return true;
		}
	}

	@Override
	public void onClickMapPoi(MapPoi mapPoi) {
		
	}

	@Override
	public void onGetCurrentMap(Bitmap bitMap) {
		
	}

	@Override
	public void onMapAnimationFinish() {
		
	}

	@Override
	public void onMapMoveFinish() {
		System.out.println("+++++++++ onMapMoveFinish +++++++++++++");
		mMapView.removeView(popView);
		zoomLevel = mMapView.getZoomLevel();
		GeoPoint gp = mMapView.getMapCenter();
		if (gp != null) {
			latitude = gp.getLatitudeE6();
			longitude = gp.getLongitudeE6();
		}
		mMapController.animateTo(gp);
		mMapView.refresh();
		try {
			Thread.sleep(500);
			handler.sendEmptyMessage(init_reports);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public void searchAddress() {
		try {
			GeoPoint gp = new GeoPoint(latitude, longitude);
			mMapController.animateTo(gp);
			mMapView.refresh();
			Thread.sleep(500);
			handler.sendEmptyMessage(init_reports);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void load() {
		mainActivity.menu.clear();
		mainActivity.setSupportProgressBarIndeterminateVisibility(true);
		UICore.eventTask(this, mainActivity, load_reports_data, null, false);
	}
	
	private void loadFinish() {
		mainActivity.setSupportProgressBarIndeterminateVisibility(false);
		if (mainActivity.actionBar.getSelectedNavigationIndex() == 0) {
			mainActivity.setMapMenu();
		}
	}

	@Override
	public void execute(int mes, Object obj) {
		switch (mes) {
		case load_reports_data:
//			loadReports();
			System.out.println("+++++++++++ map load reports ++++++++++++");
			mainActivity.filterReports();
			break;

		default:
			break;
		}
	}
	
//	private void loadReports() {
//		try {
//			GeoPoint leftGp = Utils.getLeftTopPoint(mMapView);
//			GeoPoint rightGp = Utils.getRightBottmPoint(mMapView);
//			StringBuilder builder = new StringBuilder();
//			builder.append(UrlConfig.reports);
//			builder.append("?auth_token=");
//			builder.append(AppContext.getInstance().getAuthToken());
//			builder.append("&min_y=");
//			builder.append(String.valueOf(leftGp.getLatitudeE6() / 1E6));
//			builder.append("&min_x=");
//			builder.append(String.valueOf(leftGp.getLongitudeE6() / 1E6));
//			builder.append("&max_y=");
//			builder.append(String.valueOf(rightGp.getLatitudeE6() / 1E6));
//			builder.append("&max_x=");
//			builder.append(String.valueOf(rightGp.getLongitudeE6() / 1E6));
//			if (mainActivity.getHomeFragment().report_type != 0) {
//				builder.append("&r_type=");
//				builder.append(String.valueOf(mainActivity.getHomeFragment().report_type));
//			}
//			if (mainActivity.getHomeFragment().report_time != 0) {
//				builder.append("&r_time=");
//				builder.append(String.valueOf(mainActivity.getHomeFragment().report_time));
//			}
//			String response = HttpUtils.doGet(builder.toString());
//			if (StringUtil.isNotBlank(response)) {
//				Gson gson = new Gson();
//				ReportInfoGson reportGson = gson.fromJson(response, ReportInfoGson.class);
//				if (reportGson != null) {
//					reports = reportGson.getReports();
//					mainActivity.setReports(reports);
//				}
//			}
//			handler.sendEmptyMessage(load_reports_data);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}
	
	public int getLatitude() {
		return latitude;
	}
	
	public int getLongitude() {
		return longitude;
	}
	
	public class ReportOverlayItem extends OverlayItem {
		
		private ReportEntity entry;

		public ReportOverlayItem(GeoPoint arg0, String arg1, String arg2) {
			super(arg0, arg1, arg2);
		}

		public ReportEntity getEntry() {
			return entry;
		}

		public void setEntry(ReportEntity entry) {
			this.entry = entry;
		}
		
	}
	
	public void setLatitude(int latitude) {
		this.latitude = latitude;
	}
	
	public void setLongitude(int longitude) {
		this.longitude = longitude;
	}
	
	public void initFilterView() {
		try {
			firstReportType = false;
			firstReportTime = false;
			if (mainLayout != null) {
				filterView = mainLayout.findViewById(R.id.filter_layout);
				filterView.setVisibility(View.GONE);
				Spinner reportTypeSpinner = (Spinner) mainLayout.findViewById(R.id.report_type_spinner);
				Spinner reportTimeSpinner = (Spinner) mainLayout.findViewById(R.id.report_time_spinner);
				MyArrayAdapter reportTypeAdapter = new MyArrayAdapter(mainActivity, R.layout.spinner_item);
				reportTypeAdapter.addAll(getResources().getStringArray(R.array.reportType));
				reportTypeAdapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
				reportTypeSpinner.setAdapter(reportTypeAdapter);
				
				MyArrayAdapter reportTimeAdapter = new MyArrayAdapter(mainActivity, R.layout.spinner_item);
				reportTimeAdapter.addAll(getResources().getStringArray(R.array.reportTime));
				reportTimeAdapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
				reportTimeSpinner.setAdapter(reportTimeAdapter);
				reportTypeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
						mainActivity.report_type = arg2;
						if (firstReportType) {
							filterView.setVisibility(View.GONE);
							if (mainActivity.listFragment != null) {
								mainActivity.listFragment.filterView.setVisibility(View.GONE);
								mainActivity.listFragment.initFilterTips();
							}
							initFilterTips();
							load();
						}
						firstReportType = true;
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
						
					}
				});
				reportTimeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
						mainActivity.report_time = arg2;
						if (firstReportTime) {
							filterView.setVisibility(View.GONE);
							if (mainActivity.listFragment != null) {
								mainActivity.listFragment.filterView.setVisibility(View.GONE);
								mainActivity.listFragment.initFilterTips();
							}
							initFilterTips();
							load();
						}
						firstReportTime = true;
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
						
					}
				});
				reportTypeSpinner.setSelection(mainActivity.report_type);
				reportTypeSpinner.setSelected(true);
				reportTimeSpinner.setSelection(mainActivity.report_time);
				reportTimeSpinner.setSelected(true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void initFilterTips() {
		View filterTipsView = mainLayout.findViewById(R.id.home_filter_tips);
		if (mainActivity.report_time == 0 && mainActivity.report_type == 0) {
			filterTipsView.setVisibility(View.GONE);
		} else {
			TextView tv_type = (TextView) filterTipsView.findViewById(R.id.filter_tv);
			tv_type.setText(Utils.getReportTime(mainActivity)[mainActivity.report_time] + "发生的" +
			               Utils.getReportType(mainActivity)[mainActivity.report_type] + "事件");
			filterTipsView.setVisibility(View.VISIBLE);
		}
	}
}
